/**
 * @file file_transfer.h
 * @brief 文件传输数据模块 - 处理文件传输相关的所有数据类型
 * @details 本模块实现了104协议的文件传输数据处理功能，包括文件属性、
 *          文件传输命令、文件传输响应等数据类型的序列化和反序列化操作。
 *          支持完整的数据转换和验证功能。
 * 
 * @author zyb
 * @date 2025-10-17
 * @version 1.0
 * 
 * @note 所有函数都遵循104协议规范，确保严格的数据处理
 * @warning 数据转换失败时应返回相应的错误码，便于上层处理
 * 
 * @see protocol_types.h
 * @see buffer_utils.h
 * @see time_utils.h
 */

#ifndef FILE_TRANSFER_H
#define FILE_TRANSFER_H

#include "../../common/types/include/protocol_types.h"

#ifdef __cplusplus
extern "C" {
#endif

/* ==================== 文件传输数据类型定义 ==================== */

/**
 * @brief 文件传输操作类型枚举
 */
typedef enum {
    FILE_OP_READ_DIRECTORY = 1,             /* 读目录 */
    FILE_OP_READ_DIRECTORY_CONFIRM = 2,      /* 读目录确认 */
    FILE_OP_READ_FILE_ACTIVATE = 3,          /* 读文件激活 */
    FILE_OP_READ_FILE_ACTIVATE_CONFIRM = 4,  /* 读文件激活确认 */
    FILE_OP_READ_FILE_DATA = 5,              /* 读文件数据传输 */
    FILE_OP_READ_FILE_DATA_CONFIRM = 6,      /* 读文件数据传输确认 */
    FILE_OP_WRITE_FILE_ACTIVATE = 7,         /* 写文件激活 */
    FILE_OP_WRITE_FILE_ACTIVATE_CONFIRM = 8, /* 写文件激活确认 */
    FILE_OP_WRITE_FILE_DATA = 9,             /* 写文件数据传输 */
    FILE_OP_WRITE_FILE_DATA_CONFIRM = 10     /* 写文件数据传输确认 */
} file_operation_type_t;

/**
 * @brief 文件传输状态枚举
 */
typedef enum {
    FILE_STATUS_SUCCESS = 0,                /* 成功 */
    FILE_STATUS_FAILURE = 1,                /* 失败 */
    FILE_STATUS_UNKNOWN_ERROR = 2,          /* 未知错误 */
    FILE_STATUS_FILENAME_NOT_SUPPORTED = 3,  /* 文件名不支持 */
    FILE_STATUS_LENGTH_OUT_OF_RANGE = 4,    /* 长度超范围 */
    FILE_STATUS_CHECKSUM_ERROR = 5,          /* 校验和错误 */
    FILE_STATUS_FILE_LENGTH_MISMATCH = 6,    /* 文件长度不对应 */
    FILE_STATUS_FILE_ID_MISMATCH = 7         /* 文件ID与激活ID不一致 */
} file_status_t;

/**
 * @brief 文件属性结构
 */
typedef struct {
    u8 attributes;                          /* 文件属性 */
    u32 file_size;                          /* 文件大小 */
    cp56time2a_t file_time;                 /* 文件时间 */
} file_attributes_t;

/**
 * @brief 文件信息结构
 */
typedef struct {
    u32 file_id;                            /* 文件ID */
    char filename[256];                     /* 文件名 */
    file_attributes_t attributes;           /* 文件属性 */
} file_info_t;

/**
 * @brief 目录信息结构
 */
typedef struct {
    u32 directory_id;                       /* 目录ID */
    char directory_name[128];               /* 目录名 */
    u8 file_count;                          /* 文件数量 */
    u8 has_more;                            /* 是否有后续 */
    file_info_t* files;                     /* 文件信息数组 */
} directory_info_t;

/**
 * @brief 文件传输数据包结构
 */
typedef struct {
    u8 operation_type;                      /* 操作类型 */
    u32 file_id;                            /* 文件ID */
    u32 segment_number;                     /* 数据段号 */
    u8 has_more;                            /* 后续标志 */
    u8* data;                               /* 文件数据 */
    u32 data_length;                        /* 数据长度 */
    u8 checksum;                            /* 校验码 */
} file_transfer_packet_t;

/**
 * @brief 文件传输命令结构
 */
typedef struct {
    u8 operation_type;                      /* 操作类型 */
    u32 file_id;                            /* 文件ID */
    u32 offset;                             /* 偏移量 */
    u32 length;                             /* 长度 */
    u32 checksum;                           /* 校验码 */
} file_transfer_command_t;

/**
 * @brief 文件传输响应结构
 */
typedef struct {
    u8 operation_type;                      /* 操作类型 */
    u32 file_id;                            /* 文件ID */
    u16 error_code;                         /* 错误码 */
    u32 data_length;                        /* 数据长度 */
    u8* data;                               /* 响应数据 */
} file_transfer_response_t;

/**
 * @brief 文件传输会话结构
 */
typedef struct {
    u32 session_id;                         /* 会话ID */
    file_operation_type_t operation_type;   /* 操作类型 */
    u32 file_id;                            /* 文件ID */
    char filename[256];                     /* 文件名 */
    u32 file_size;                          /* 文件大小 */
    u32 transferred_size;                   /* 已传输大小 */
    u32 segment_count;                      /* 段数 */
    u32 current_segment;                    /* 当前段号 */
    file_status_t status;                   /* 传输状态 */
    cp56time2a_t start_time;                /* 开始时间 */
    cp56time2a_t end_time;                  /* 结束时间 */
} file_transfer_session_t;

/**
 * @brief 文件传输数据组
 */
typedef struct {
    file_transfer_session_t* sessions;      /* 传输会话数组 */
    u32 count;                              /* 会话个数 */
    u32 max_count;                          /* 最大会话个数 */
} file_transfer_data_group_t;

/* ==================== 文件属性处理函数 ==================== */

/**
 * @brief 文件属性转换为字节数组
 * @details 将文件属性结构转换为104协议规定的字节数组格式。
 *          按照协议规范进行数据序列化。
 * 
 * @param file_attr 文件属性结构，不能为NULL
 * @param buffer 输出缓冲区，不能为NULL
 * @param buffer_size 缓冲区大小
 * @param actual_length 实际写入长度输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据序列化
 * @warning 缓冲区大小必须足够容纳转换后的数据
 * 
 * @see bytes_to_file_attributes
 * @see validate_file_attributes
 */
protocol_error_t file_attributes_to_bytes(const file_attributes_t* file_attr,
                                        u8* buffer, u32 buffer_size, u32* actual_length);

/**
 * @brief 字节数组转换为文件属性
 * @details 将104协议规定的字节数组格式转换为文件属性结构。
 *          按照协议规范进行数据反序列化。
 * 
 * @param data 字节数组，不能为NULL
 * @param length 数据长度
 * @param file_attr 文件属性结构输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 数据长度不足
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据反序列化
 * @warning 数据长度必须足够容纳文件属性
 * 
 * @see file_attributes_to_bytes
 * @see validate_file_attributes
 */
protocol_error_t bytes_to_file_attributes(const u8* data, u32 length,
                                         file_attributes_t* file_attr);

/**
 * @brief 验证文件属性
 * @details 验证文件属性结构的完整性和有效性。
 *          检查文件大小等的有效性。
 * 
 * @param file_attr 文件属性结构，不能为NULL
 * @return 验证结果
 *         - 1: 文件属性有效
 *         - 0: 文件属性无效
 * 
 * @note 验证文件大小等的有效性
 * @warning 输入指针不能为NULL
 * 
 * @see is_file_size_valid
 * @see file_attributes_t
 */
int validate_file_attributes(const file_attributes_t* file_attr);

/* ==================== 文件传输命令处理函数 ==================== */

/**
 * @brief 文件传输命令转换为字节数组
 * @details 将文件传输命令结构转换为104协议规定的字节数组格式。
 *          按照协议规范进行数据序列化。
 * 
 * @param command 文件传输命令结构，不能为NULL
 * @param buffer 输出缓冲区，不能为NULL
 * @param buffer_size 缓冲区大小
 * @param actual_length 实际写入长度输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据序列化
 * @warning 缓冲区大小必须足够容纳转换后的数据
 * 
 * @see bytes_to_file_transfer_command
 * @see validate_file_transfer_command
 */
protocol_error_t file_transfer_command_to_bytes(const file_transfer_command_t* command,
                                              u8* buffer, u32 buffer_size, u32* actual_length);

/**
 * @brief 字节数组转换为文件传输命令
 * @details 将104协议规定的字节数组格式转换为文件传输命令结构。
 *          按照协议规范进行数据反序列化。
 * 
 * @param data 字节数组，不能为NULL
 * @param length 数据长度
 * @param command 文件传输命令结构输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 数据长度不足
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据反序列化
 * @warning 数据长度必须足够容纳文件传输命令
 * 
 * @see file_transfer_command_to_bytes
 * @see validate_file_transfer_command
 */
protocol_error_t bytes_to_file_transfer_command(const u8* data, u32 length,
                                               file_transfer_command_t* command);

/**
 * @brief 验证文件传输命令
 * @details 验证文件传输命令结构的完整性和有效性。
 *          检查文件ID、操作类型、偏移、长度等的有效性。
 * 
 * @param command 文件传输命令结构，不能为NULL
 * @return 验证结果
 *         - 1: 文件传输命令有效
 *         - 0: 文件传输命令无效
 * 
 * @note 验证文件ID、操作类型、偏移、长度等的有效性
 * @warning 输入指针不能为NULL
 * 
 * @see is_file_id_valid
 * @see is_file_operation_type_valid
 * @see is_file_offset_valid
 * @see is_file_length_valid
 * @see file_transfer_command_t
 */
int validate_file_transfer_command(const file_transfer_command_t* command);

/* ==================== 文件传输响应处理函数 ==================== */

/**
 * @brief 文件传输响应转换为字节数组
 * @details 将文件传输响应结构转换为104协议规定的字节数组格式。
 *          按照协议规范进行数据序列化。
 * 
 * @param response 文件传输响应结构，不能为NULL
 * @param buffer 输出缓冲区，不能为NULL
 * @param buffer_size 缓冲区大小
 * @param actual_length 实际写入长度输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据序列化
 * @warning 缓冲区大小必须足够容纳转换后的数据
 * 
 * @see bytes_to_file_transfer_response
 * @see validate_file_transfer_response
 */
protocol_error_t file_transfer_response_to_bytes(const file_transfer_response_t* response,
                                                u8* buffer, u32 buffer_size, u32* actual_length);

/**
 * @brief 字节数组转换为文件传输响应
 * @details 将104协议规定的字节数组格式转换为文件传输响应结构。
 *          按照协议规范进行数据反序列化。
 * 
 * @param data 字节数组，不能为NULL
 * @param length 数据长度
 * @param response 文件传输响应结构输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 数据长度不足
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据反序列化
 * @warning 数据长度必须足够容纳文件传输响应
 * 
 * @see file_transfer_response_to_bytes
 * @see validate_file_transfer_response
 */
protocol_error_t bytes_to_file_transfer_response(const u8* data, u32 length,
                                                file_transfer_response_t* response);

/**
 * @brief 验证文件传输响应
 * @details 验证文件传输响应结构的完整性和有效性。
 *          检查文件ID、状态、错误码、数据长度等的有效性。
 * 
 * @param response 文件传输响应结构，不能为NULL
 * @return 验证结果
 *         - 1: 文件传输响应有效
 *         - 0: 文件传输响应无效
 * 
 * @note 验证文件ID、状态、错误码、数据长度等的有效性
 * @warning 输入指针不能为NULL
 * 
 * @see is_file_id_valid
 * @see is_file_status_valid
 * @see is_file_error_code_valid
 * @see is_file_data_length_valid
 * @see file_transfer_response_t
 */
int validate_file_transfer_response(const file_transfer_response_t* response);

/* ==================== 辅助函数 ==================== */

/**
 * @brief 获取文件属性大小
 * @details 获取文件属性结构在字节数组中的大小。
 *          用于缓冲区大小计算。
 * 
 * @return 文件属性大小（字节）
 * 
 * @note 文件属性大小：12字节（文件属性1字节 + 文件大小4字节 + 文件时间7字节）
 * @warning 此函数是线程安全的
 * 
 * @see get_file_transfer_command_size
 * @see get_file_transfer_response_size
 * @see file_attributes_t
 */
u32 get_file_attributes_size(void);

/**
 * @brief 获取文件传输命令大小
 * @details 获取文件传输命令结构在字节数组中的大小。
 *          用于缓冲区大小计算。
 * 
 * @return 文件传输命令大小（字节）
 * 
 * @note 文件传输命令大小：17字节（文件ID4字节 + 操作类型1字节 + 偏移4字节 + 长度4字节 + 校验和4字节）
 * @warning 此函数是线程安全的
 * 
 * @see get_file_attributes_size
 * @see get_file_transfer_response_size
 * @see file_transfer_command_t
 */
u32 get_file_transfer_command_size(void);

/**
 * @brief 获取文件传输响应大小
 * @details 获取文件传输响应结构在字节数组中的大小。
 *          用于缓冲区大小计算。
 * 
 * @return 文件传输响应大小（字节）
 * 
 * @note 文件传输响应大小：11字节（文件ID4字节 + 状态1字节 + 错误码2字节 + 数据长度4字节）
 * @warning 此函数是线程安全的
 * 
 * @see get_file_attributes_size
 * @see get_file_transfer_command_size
 * @see file_transfer_response_t
 */
u32 get_file_transfer_response_size(void);

/* ==================== 文件操作类型处理函数 ==================== */

/**
 * @brief 获取文件操作类型名称
 * @details 根据文件操作类型枚举值获取对应的中文名称。
 *          用于调试和日志输出。
 * 
 * @param type 文件操作类型枚举值
 * @return 文件操作类型名称字符串
 * 
 * @note 返回的字符串是静态的，不需要释放
 * @warning 无效类型返回"未知类型"
 * 
 * @see file_operation_type_t
 * @see get_file_operation_type_description
 */
const char* get_file_operation_type_name(file_operation_type_t type);

/**
 * @brief 获取文件操作类型描述
 * @details 根据文件操作类型枚举值获取对应的详细描述。
 *          用于调试和日志输出。
 * 
 * @param type 文件操作类型枚举值
 * @return 文件操作类型描述字符串
 * 
 * @note 返回的字符串是静态的，不需要释放
 * @warning 无效类型返回"未知类型"
 * 
 * @see file_operation_type_t
 * @see get_file_operation_type_name
 */
const char* get_file_operation_type_description(file_operation_type_t type);

/* ==================== 文件状态处理函数 ==================== */

/**
 * @brief 获取文件状态名称
 * @details 根据文件状态枚举值获取对应的中文名称。
 *          用于调试和日志输出。
 * 
 * @param status 文件状态枚举值
 * @return 文件状态名称字符串
 * 
 * @note 返回的字符串是静态的，不需要释放
 * @warning 无效状态返回"未知状态"
 * 
 * @see file_status_t
 * @see get_file_status_description
 */
const char* get_file_status_name(file_status_t status);

/**
 * @brief 获取文件状态描述
 * @details 根据文件状态枚举值获取对应的详细描述。
 *          用于调试和日志输出。
 * 
 * @param status 文件状态枚举值
 * @return 文件状态描述字符串
 * 
 * @note 返回的字符串是静态的，不需要释放
 * @warning 无效状态返回"未知状态"
 * 
 * @see file_status_t
 * @see get_file_status_name
 */
const char* get_file_status_description(file_status_t status);

/* ==================== 文件传输验证函数 ==================== */

/**
 * @brief 验证文件ID
 * @details 验证文件ID是否在有效范围内。
 *          文件ID范围：1-4294967295
 * 
 * @param file_id 文件ID
 * @return 验证结果
 *         - 1: 文件ID有效
 *         - 0: 文件ID无效
 * 
 * @note 文件ID范围：1-4294967295
 * @warning 文件ID不能为0
 * 
 * @see is_file_length_valid
 * @see is_file_type_valid
 */
int is_file_id_valid(u32 file_id);

/**
 * @brief 验证文件长度
 * @details 验证文件长度是否在有效范围内。
 *          文件长度范围：0-4294967295
 * 
 * @param file_length 文件长度
 * @return 验证结果
 *         - 1: 文件长度有效
 *         - 0: 文件长度无效
 * 
 * @note 文件长度范围：0-4294967295
 * @warning 文件长度不能为负数
 * 
 * @see is_file_id_valid
 * @see is_file_type_valid
 */
int is_file_length_valid(u32 file_length);

/**
 * @brief 验证文件类型
 * @details 验证文件类型是否在有效范围内。
 *          文件类型范围：0-4294967295
 * 
 * @param file_type 文件类型
 * @return 验证结果
 *         - 1: 文件类型有效
 *         - 0: 文件类型无效
 * 
 * @note 文件类型范围：0-4294967295
 * @warning 文件类型不能为负数
 * 
 * @see is_file_id_valid
 * @see is_file_length_valid
 */
int is_file_type_valid(u32 file_type);

/**
 * @brief 验证文件操作类型
 * @details 验证文件操作类型是否在有效范围内。
 *          文件操作类型范围：1-10
 * 
 * @param operation_type 文件操作类型
 * @return 验证结果
 *         - 1: 文件操作类型有效
 *         - 0: 文件操作类型无效
 * 
 * @note 文件操作类型范围：1-10
 * @warning 文件操作类型不能为0
 * 
 * @see is_file_status_valid
 * @see is_file_error_code_valid
 */
int is_file_operation_type_valid(file_operation_type_t operation_type);

/**
 * @brief 验证文件偏移
 * @details 验证文件偏移是否在有效范围内。
 *          文件偏移范围：0-4294967295
 * 
 * @param offset 文件偏移
 * @return 验证结果
 *         - 1: 文件偏移有效
 *         - 0: 文件偏移无效
 * 
 * @note 文件偏移范围：0-4294967295
 * @warning 文件偏移不能为负数
 * 
 * @see is_file_length_valid
 * @see is_file_id_valid
 */
int is_file_offset_valid(u32 offset);

/**
 * @brief 验证文件状态
 * @details 验证文件状态是否在有效范围内。
 *          文件状态范围：0-7
 * 
 * @param status 文件状态
 * @return 验证结果
 *         - 1: 文件状态有效
 *         - 0: 文件状态无效
 * 
 * @note 文件状态范围：0-7
 * @warning 文件状态不能为负数
 * 
 * @see is_file_operation_type_valid
 * @see is_file_error_code_valid
 */
int is_file_status_valid(file_status_t status);

/**
 * @brief 验证文件错误码
 * @details 验证文件错误码是否在有效范围内。
 *          文件错误码范围：0-65535
 * 
 * @param error_code 文件错误码
 * @return 验证结果
 *         - 1: 文件错误码有效
 *         - 0: 文件错误码无效
 * 
 * @note 文件错误码范围：0-65535
 * @warning 文件错误码不能为负数
 * 
 * @see is_file_status_valid
 * @see is_file_operation_type_valid
 */
int is_file_error_code_valid(u16 error_code);

/**
 * @brief 验证文件数据长度
 * @details 验证文件数据长度是否在有效范围内。
 *          文件数据长度范围：0-4294967295
 * 
 * @param data_length 文件数据长度
 * @return 验证结果
 *         - 1: 文件数据长度有效
 *         - 0: 文件数据长度无效
 * 
 * @note 文件数据长度范围：0-4294967295
 * @warning 文件数据长度不能为负数
 * 
 * @see is_file_length_valid
 * @see is_file_offset_valid
 */
int is_file_data_length_valid(u32 data_length);

/**
 * @brief 验证文件属性
 * @details 验证文件属性结构是否有效。
 *          检查文件大小是否在有效范围内。
 * 
 * @param file_attr 文件属性结构指针
 * @return 验证结果
 *         - 1: 文件属性有效
 *         - 0: 文件属性无效
 * 
 * @note 文件大小范围：0-4294967295
 * @warning 文件属性指针不能为NULL
 * 
 * @see file_attributes_t
 * @see is_file_size_valid
 */
int is_file_attributes_valid(const file_attributes_t* file_attr);

/**
 * @brief 验证文件大小
 * @details 验证文件大小是否在有效范围内。
 *          文件大小范围：0-4294967295
 * 
 * @param file_size 文件大小
 * @return 验证结果
 *         - 1: 文件大小有效
 *         - 0: 文件大小无效
 * 
 * @note 文件大小范围：0-4294967295
 * @warning 文件大小不能为负数
 * 
 * @see is_file_attributes_valid
 * @see is_file_length_valid
 */
int is_file_size_valid(u32 file_size);

/**
 * @brief 验证文件传输命令
 * @details 验证文件传输命令结构是否有效。
 *          检查文件ID、操作类型、偏移、长度等的有效性。
 * 
 * @param command 文件传输命令结构指针
 * @return 验证结果
 *         - 1: 文件传输命令有效
 *         - 0: 文件传输命令无效
 * 
 * @note 验证文件ID、操作类型、偏移、长度等的有效性
 * @warning 文件传输命令指针不能为NULL
 * 
 * @see file_transfer_command_t
 * @see is_file_id_valid
 * @see is_file_operation_type_valid
 * @see is_file_offset_valid
 * @see is_file_length_valid
 */
int is_file_transfer_command_valid(const file_transfer_command_t* command);

/**
 * @brief 验证文件传输响应
 * @details 验证文件传输响应结构是否有效。
 *          检查文件ID、操作类型等的有效性。
 * 
 * @param response 文件传输响应结构指针
 * @return 验证结果
 *         - 1: 文件传输响应有效
 *         - 0: 文件传输响应无效
 * 
 * @note 验证文件ID、操作类型等的有效性
 * @warning 文件传输响应指针不能为NULL
 * 
 * @see file_transfer_response_t
 * @see is_file_id_valid
 * @see is_file_operation_type_valid
 */
int is_file_transfer_response_valid(const file_transfer_response_t* response);

#ifdef __cplusplus
}
#endif

#endif /* FILE_TRANSFER_H */
